from django.shortcuts import render,redirect
#导包
from django.http import HttpResponse,HttpResponseRedirect,JsonResponse
#导入类视图
from django.views import View

from myapp.models import User
import json
from django.core.serializers import serialize
from rest_framework.response import Response
from rest_framework.views import APIView
#导入加密库
import hashlib
#导入图片库
#绘画库
from PIL import ImageDraw
#字体库
from PIL import ImageFont
#图片库
from PIL import Image
#随机库
import random
#文件流
import io

import requests

#导入上传文件夹配置
from mydjango.settings import UPLOAD_ROOT
import os

#导入原生sql模块
from django.db import connection

import jwt

#导入redis数据库
import redis

#导入时间模块
import time

#导入公共目录变量
from mydjango.settings import BASE_DIR

#导包
from django.db.models import Q,F

#导入dwebsocket的库
from dwebsocket.decorators import accept_websocket
import uuid

#导入序列化类
from myapp.myser import UserSer


#导入中间件
from django.utils.deprecation import MiddlewareMixin


#建立redis链接
#定义ip
host = 'localhost'
#建立服务连接
r = redis.Redis(host=host)


#创建客户列表
clients = {}

@accept_websocket
def link(request):

    #判断是不是websocket请求
    if request.is_websocket():
        #创建userid
        userid = str(uuid.uuid1())

    #创建链接
    while True:
        #声明信息
        message = request.websocket.wait()
        if not message:
            break
        else:
            print('链接成功'+str(message,encoding="utf-8"))
            #保存客户信息
            clients[userid] = request.websocket


#读取聊天记录接口
def readlog(request):

    #记录聊天日志
    talk_log = os.path.join(BASE_DIR,"mytalk.txt")

    result = []
    with open(talk_log,'r',encoding="utf-8") as f:
        for line in f.readlines():
            result.append(line.replace("\n",""))

    #返回聊天记录
    return HttpResponse(json.dumps(result,ensure_ascii=False),content_type='application/json')


#发送消息接口
def send(request):

    #获取消息i
    msg = request.GET.get('msg')

    #记录聊天日志
    talk_log = os.path.join(BASE_DIR,"mytalk.txt")

    with open(talk_log,'a',encoding="utf-8") as f:
        f.write('%s\n' % msg)

    #遍历客户列表，发送消息
    for client in clients:
        clients[client].send(msg.encode('utf-8'))
    
    return HttpResponse({'msg':'ok'})




#获取在线人数接口
class GetOnLines(APIView):

    def get(self,request):

        #获取客户端ip
        if 'HTTP_X_FORWARDED_FOR' in request.META:
            ip = request.META.get('HTTP_X_FORWARDED_FOR')
        else:
            ip = request.META.get('REMOTE_ADDR')


        #将客户端ip进行存储(redis)
        r.sadd('onlines',ip)
        #过期时间 单位秒
        r.expire('onlines',10)

        #获取成员数量
        myset = r.smembers('onlines')


        ret = {}
        ret['onlines'] = len(myset)

        return Response(ret)



#上传头像
class UploadImg(View):

    def post(self,request):

        #接收文件
        img = request.FILES.get("file")
        #建立文件流对象
        f = open(os.path.join(UPLOAD_ROOT,'',img.name),'wb')
        #写文件，遍历写入
        for chunk in img.chunks():
            f.write(chunk)
        #关闭文件流
        f.close()
        #返回图片文件名
        return HttpResponse(json.dumps({'filename':img.name},ensure_ascii=False),content_type='application/json')



#定义微博回调视图
def wb_back(request):

    #获取回调的code
    code = request.GET.get('code')

    #定义认证地址
    access_token_url = 'https://api.weibo.com/oauth2/access_token'

    #发起请求，交换sina的id
    re_dict = requests.post(

        access_token_url,
        data={
            "client_id":'2636039333',   #应用id
            "client_secret":"4e2fbdb39432c31dc5c2f90be3afa5ce",  #密钥
            "grant_type":"authorization_code",  #授权方式
            "code":code,  #code
            "redirect_uri":"http://127.0.0.1:8000/md_admin/weibo"   #回调网址
        }
    )

    #获取返回值
    re_dict = re_dict.text
    #强转
    re_dict = eval(re_dict)

    print(re_dict)
    
    #判断是否为第一次登录
    user = User.objects.filter(username=str(re_dict['uid'])).first()

    sina_id = ''
    user_id = ''

    if user:
        #代表曾经用过新浪登录
        sina_id = user.username
        user_id = user.id
    else:
        #代表首次登录，入库
        user = User(username=str(re_dict['uid']),password='')
        #保存入库
        user.save()
        sina_id = str(re_dict['uid'])
        #查询用户id
        user = User.objects.filter(username=str(re_dict['uid'])).first()
        user_id = user.id

    #增加token密钥
    encode_jwt = jwt.encode({'uid':user_id},'123',algorithm='HS256')
    #转码
    encode_str = str(encode_jwt,'utf-8')

    url = "http://localhost:8080?sina_id="+str(sina_id)+"&uid="+str(user_id)+"&token="+encode_str

    print(url)

    #进行跳转
    return redirect(url)


#定义随机验证码类
class MyCode(View):

    #定义随机颜色
    def get_random_color(self):
        R = random.randrange(255)
        G = random.randrange(255)
        B = random.randrange(255)
        return (R,G,B)

    def get(self,request):
        #定义画布
        img_size = (120,50)
        #定义画笔
        image = Image.new("RGB",img_size,'white')
        #定义绘图对象
        draw = ImageDraw.Draw(image,'RGB')
        #定义随机串
        source = '0123456789asd'
        #定义好容器，方便存入redis
        code_str = ''
        for i in range(4):
            #获取随机颜色
            text_color = self.get_random_color()
            #获取随机字符串
            tmp_num = random.randrange(len(source))
            #通过下标获取字符集
            random_str = source[tmp_num]
            #添加到容器
            code_str += random_str
            #绘制图像
            draw.text((10+30*i,20),random_str,text_color)
        #定义缓冲区
        buf = io.BytesIO()
        #保存到缓冲区
        image.save(buf,'png')
        #保存到redis
        r.set('code',code_str)
        #存储到session
        request.session['code'] = code_str

        return HttpResponse(buf.getvalue(),'image/png')



#获取用户信息接口
class UserGetOne(APIView):

    def get(self,request):

        #接收参数
        uid = request.GET.get('uid','')

        #查询数据
        user = User.objects.get(id=int(uid))

        #序列化
        user_ser = UserSer(user)

        #返回数据

        return Response(user_ser.data)
        




#用户修改接口
class UserUpdate(APIView):

    def get(self,request):

        #接收参数
        uid = request.GET.get('uid','')

        print(uid)

        #图片（原始文件名）
        img = request.GET.get('img','')

        #查询数据
        user = User.objects.get(id=int(uid))

        #保存数据
        user.img = img
        user.save()

        #返回
        res = {}
        res['code'] = 200
        res['message'] = '用户更新成功'
        return Response(res)






#登录接口
class Login(APIView):

    def get(self,request):

        #接收参数
        username = request.GET.get('username','')
        password = request.GET.get('password','')

        #查询数据
        user = User.objects.filter(username=username,password=make_password(password)).first()

        if user:
            res = {}
            res['code'] = 200
            res['message'] = '登录成功'
            res['username'] = user.username
            res['uid'] = user.id
            return Response(res)
        else:
            res = {}
            res['code'] = 405
            res['message'] = '您的用户名或者密码错误'
            return Response(res)





#md5加密方法
def make_password(mypass):

    #建立md5对象
    md5 = hashlib.md5()
    #转码
    mypass = str(mypass).encode(encoding="utf-8")
    #加密操作
    md5.update(mypass)
    #生成密文
    password = md5.hexdigest()
    #返回密文
    return password

#注册接口
class Register(APIView):

    def get(self,request):

        #接收参数
        username = request.GET.get('username','')
        password = request.GET.get('password','')
        code = request.GET.get('code','')

        #获取redis中的验证码
        mycode = r.get('code')
        #转码
        mycode = mycode.decode("utf-8")

        #获取session中的验证码
        mycode_session = request.session.get('code',None)

        print(mycode_session)

        #进行比对操作
        if code != mycode:
            res = {}
            res['code'] = 405
            res['message'] = '验证码输入错误'
            return Response(res)

        #排重操作
        user = User.objects.filter(username=username).first()

        if user:
            res = {}
            res['code'] = 405
            res['message'] = '用户已经存在'
            return Response(res)

        #进行入库操作
        #实例化对象
        user = User(username=username,password=make_password(password))
        #保存
        user.save()

        #返回结果
        res = {}
        res['code'] = 200
        res['message'] = '注册成功'

        return Response(res)